#pragma once
//#ifndef DYNAMICDATA_H
//#define DYNAMICDATA_H
#include "StdAfx.h"

#include <map>


#ifndef NOTYPECHECK
#include<assert.h>
#define VLARE_TYPECHECK(dd,t) assert((dd)->type==DynamicData::t)
#else
#define VLARE_TYPECHECK(dd,t)
#endif

#define VLARE_ENABLE_ARRAY_TYPE

/////could cause perfomance penalty because of bigger union-size
//#define VLARE_ENABLE_HASHMAP_TYPE

struct CostumeMatrix;
struct CostumeRenderData;

/// define the desired floatingpoint-type for Vlare
#ifndef _Vloat
#define _Vloat double
#endif

struct DynamicData;


typedef _Vloat Vloat;
typedef Vloat Coord1D;

/// A VunctionCall can be called by anyone
typedef DynamicData (*VunctionCall)(DynamicData params);

/// A Vunction is the one to implement and register
/**
 * A call to a Vunction is wrapped by a Hook. Element and property-ame data is passed on.
 **/
typedef DynamicData (*Vunction)(void/*Vlare::Element*/ *const pElem, const char *const szName,  DynamicData params);


struct DynamicData
{
	enum VLARE_TYPE {
		TYPE_STRING,	//<Text
		TYPE_INT,		//<Integral type
		TYPE_FLOAT,		//<Floatingpointvalue (can also be double)
		TYPE_POINTER,	//<Pointer
		TYPE_ARRAY,		//<a field of DynamicData(s) and a trailing 
		TYPE_HASHMAP,	//<a Hashmap (if this is enabled during compilation)
		TYPE_VUNCTION,	//<a Function, taking DynamicData as a parameter and returns a DynamicData.
		TYPE_NOTIFY,	//< dummy for Dataless Notification this can be returned by Vunctions when invoked. Moreover this can be directly the Value of an event, more then one Function (Listener) can be invoked then via Hooks.
		TYPE_NOT_SET,
		TYPE_NULL		//< Beware: This is the type. There is a difference to TYPE_POINTER and _dynDat==null!
	} type;
	/**
	 * If the content is a Vunction, there is a recursion
	 *  DynamicData > _dynDat > Vunction > DynamicData
	 */
	union _dynDat {
		const char* szVal;
		int iVal;
		Vloat dVal;
		void* pVal;
	#ifdef VLARE_ENABLE_ARRAY_TYPE
		/// arrays must be malloced, they are freed by Vlare-core when not longer needed
		DynamicData* arr;
	#endif
	#ifdef VLARE_ENABLE_HASHMAP_TYPE
		vlareHashMap map;
	#endif
		Vunction pfn;

		_dynDat(const char* szVal);
		_dynDat(int iVal);
		_dynDat(Vloat dVal);
		_dynDat(void* pVal);
		_dynDat(DynamicData* aVal);
		_dynDat(Vunction pfnVal);
		_dynDat(const _dynDat& val);
	} val;
	DynamicData();
	DynamicData(const char* const val);
	DynamicData(int val);
	DynamicData(Vloat val);
	DynamicData(void* val);
	DynamicData(DynamicData* allocatedArray);
	DynamicData(Vunction val);
	DynamicData(const DynamicData& val);
	
	operator const char* () const;
	operator int () const;
	operator Vloat () const;
	operator void* () const;
	//operator DynamicData* () const;
	operator Vunction () const;
	//DynamicData& operator= (const DynamicData& );
	~DynamicData(void);
};
//#endif